<template>
  <div class="chat-function">
    <div class="modern-chat-container">
      <!-- 聊天头部 -->
      <div class="chat-header">
        <div class="header-left">
          <div class="ai-avatar-large">
            <el-icon size="20" color="white"><ChatDotRound /></el-icon>
          </div>
          <div class="header-info">
            <h3>AI智能助手</h3>
            <p>在线 · 随时为您服务</p>
          </div>
        </div>
        <div class="header-center">
          <div class="current-user">
            <el-avatar :size="28" :src="userInfo?.avatar">
              <el-icon size="16"><User /></el-icon>
            </el-avatar>
            <span>{{ userInfo?.username || '用户' }}</span>
          </div>
        </div>
        <div class="header-actions">
          <el-button type="text" @click="clearMessages" class="clear-btn">
            <el-icon><Delete /></el-icon>
          </el-button>
        </div>
      </div>

      <!-- 消息列表 -->
      <div class="messages-container" ref="messagesRef">
        <div v-if="messages.length === 0" class="welcome-message">
          <div class="welcome-icon">
            <el-icon size="80" color="#67c23a"><ChatDotRound /></el-icon>
          </div>
          <h3>欢迎使用伴伴AI对话</h3>
          <p>我是您的伴伴AI助手，可以帮您解答各种学习问题</p>

          <!-- 快速问题模板 -->
          <div class="quick-questions">
            <h4>快速开始：</h4>
            <div class="question-tags">
              <el-tag
                v-for="question in quickQuestions"
                :key="question"
                @click="selectQuickQuestion(question)"
                class="question-tag"
                type="info"
              >
                {{ question }}
              </el-tag>
            </div>
          </div>
        </div>

        <!-- 消息列表 -->
        <div v-for="message in messages" :key="message.id" class="message-item">
          <!-- 用户消息 - 右侧显示 -->
          <div v-if="message.type === 'user'" class="user-message">
            <div class="message-content">
              <div v-if="message.image" class="message-image">
                <img :src="message.image" alt="用户图片" @click="previewImage(message.image)" />
                <div v-if="message.ocrText" class="ocr-text">
                  <el-icon><Document /></el-icon>
                  <span>识别文字：{{ message.ocrText }}</span>
                </div>
              </div>
              <div v-if="message.content" class="message-text">{{ message.content }}</div>
              <div class="message-time">{{ formatTime(message.timestamp || message.time) }}</div>
            </div>
            <div class="user-avatar">
              <div class="user-avatar-circle">
                <el-icon size="18"><User /></el-icon>
              </div>
            </div>
          </div>

          <!-- AI消息 - 左侧显示 -->
          <div v-else class="ai-message">
            <div class="ai-avatar">
              <div class="ai-avatar-circle">
                <el-icon size="18"><Service /></el-icon>
              </div>
            </div>
            <div class="message-content">
              <div class="ai-name">伴伴AI</div>
              <div class="message-text"
                   :class="{ 'typing-effect': message.isTyping }"
                   v-html="formatMessage(message.content)">
              </div>
              <div v-if="message.isTyping" class="typing-indicator">
                <span class="typing-dot"></span>
                <span class="typing-dot"></span>
                <span class="typing-dot"></span>
              </div>
              <div class="message-actions">
                <div class="message-time">{{ formatTime(message.timestamp || message.time) }}</div>
                <div class="action-buttons">
                  <el-button type="text" size="small" class="action-btn"
                             @click="speakMessage(message.content)"
                             :loading="speakingMessageId === message.id">
                    <el-icon><Microphone /></el-icon>
                    {{ speakingMessageId === message.id ? '播放中...' : '语音播报' }}
                  </el-button>
                  <el-button type="text" size="small" class="action-btn"
                             @click="copyMessage(message.content)">
                    <el-icon><CopyDocument /></el-icon>
                    复制
                  </el-button>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 打字指示器 -->
        <div v-if="isTyping" class="typing-indicator">
          <div class="ai-avatar">
            <el-icon size="24" color="#67c23a"><Avatar /></el-icon>
          </div>
          <div class="typing-dots">
            <span></span>
            <span></span>
            <span></span>
          </div>
        </div>
      </div>

      <!-- 输入区域 -->
      <div class="input-area">
        <div class="input-container">
          <!-- 图片上传预览 -->
          <div v-if="uploadedImage" class="image-preview">
            <div class="preview-image">
              <img :src="uploadedImage" alt="待发送图片" />
              <div class="image-overlay">
                <el-button type="danger" size="small" @click="removeImage" class="remove-image">
                  <el-icon><Close /></el-icon>
                  删除
                </el-button>
              </div>
            </div>
            <div class="image-info">
              <span class="image-name">{{ imageName }}</span>
              <span class="image-size">{{ imageSize }}</span>
            </div>
          </div>

          <div class="input-row">
            <el-input
              v-model="inputText"
              type="textarea"
              :rows="3"
              placeholder="输入你的问题，或上传图片让AI分析..."
              :disabled="isTyping"
              @keydown.enter.exact.prevent="sendMessage"
              @keydown.enter.shift.exact="handleShiftEnter"
              resize="none"
              class="message-input"
            />

            <div class="input-actions">
              <el-upload
                :show-file-list="false"
                :before-upload="handleImageUpload"
                accept="image/jpeg,image/png,image/bmp"
                class="image-upload"
              >
                <el-tooltip content="上传图片" placement="top">
                  <el-button type="text" size="large">
                    <el-icon><Picture /></el-icon>
                  </el-button>
                </el-tooltip>
              </el-upload>

              <el-tooltip content="发送消息" placement="top">
                <el-button
                  type="primary"
                  :loading="isTyping"
                  :disabled="!inputText.trim() && !uploadedImage"
                  @click="sendMessage"
                  class="send-btn"
                >
                  <el-icon><Promotion /></el-icon>
                </el-button>
              </el-tooltip>
            </div>
          </div>

          <div class="input-tips">
            <span>按 Enter 发送，Shift + Enter 换行，支持上传图片</span>
          </div>
        </div>
      </div>
    </div>

    <!-- 图片预览对话框 -->
    <el-dialog v-model="showImagePreview" title="图片预览" width="60%">
      <img :src="previewImageUrl" alt="预览图片" style="width: 100%;" />
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, nextTick, watch, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  ChatDotRound, Delete, Avatar, CopyDocument, Close, Picture, Promotion, User, Document, Edit, Star, Microphone, Service
} from '@element-plus/icons-vue'
import { aiChat, chatWithUser, continueConversation, chatWithSession, ocrImage, getSessionMessages } from '@/api/tutor'
import { getUserInfo } from '@/utils/auth'

// Props
const props = defineProps({
  sessionId: {
    type: String,
    default: null
  }
})

// Emits
const emit = defineEmits(['message-sent'])

// 状态
const inputText = ref('')
const uploadedImage = ref('')
const isTyping = ref(false)
const messages = ref([])
const messagesRef = ref(null)
const showImagePreview = ref(false)
const previewImageUrl = ref('')
const imageName = ref('')
const speakingMessageId = ref(null)

// 获取用户信息
const userInfo = computed(() => getUserInfo())
const imageSize = ref('')

// 快速问题模板
const quickQuestions = [
  '数学题怎么解？',
  '英语语法有什么技巧？',
  '物理概念如何理解？',
  '化学方程式怎么配平？'
]

let messageId = 0

// 加载会话消息
const loadSessionMessages = async (sessionId) => {
  if (!sessionId) return

  const currentUser = userInfo.value
  const userId = currentUser?.id

  console.log('🔄 开始加载会话消息', { sessionId, userId })

  if (!userId) {
    console.log('⚠️ 用户未登录，清空消息列表')
    messages.value = []
    return
  }

  try {
    console.log('📡 调用API获取会话消息', { userId, sessionId })
    const response = await getSessionMessages({
      userId: userId,
      sessionId: sessionId
    })

    console.log('📄 API响应', response)

    if (response.success || response.code === 200) {
      const data = response.data
      console.log('✅ API调用成功，原始消息数据', data)

      // 转换Redis消息格式为前端格式
      // Redis中每条消息都有type和content字段
      const convertedMessages = []

      ;(data.messages || []).forEach((msg, index) => {
        console.log(`🔄 处理消息 ${index + 1}:`, msg)

        // 直接使用Redis中的消息格式
        if (msg.type && msg.content) {
          const convertedMsg = {
            id: msg.id || `msg_${index}_${Date.now()}`,
            type: msg.type, // 'user' 或 'ai'
            content: msg.content,
            timestamp: msg.timestamp || Date.now(),
            time: new Date(msg.timestamp || Date.now())
          }
          convertedMessages.push(convertedMsg)
          console.log(`${msg.type === 'user' ? '👤' : '🤖'} 添加${msg.type === 'user' ? '用户' : 'AI'}消息:`, convertedMsg)
        } else {
          console.warn('⚠️ 消息格式异常，跳过:', msg)
        }
      })

      console.log('📝 转换后的消息列表:', convertedMessages)
      messages.value = convertedMessages
      console.log('✅ 消息列表已更新，当前消息数量:', messages.value.length)

      nextTick(() => {
        scrollToBottom()
      })
    } else {
      console.error('❌ API调用失败:', response.message)
      console.error('❌ 完整响应:', response)
      messages.value = []
    }
  } catch (error) {
    console.error('❌ 加载会话消息异常:', error)
    messages.value = []
  }
}

// Redis会自动保存消息，不需要手动保存

// 监听会话ID变化
watch(() => props.sessionId, async (newSessionId, oldSessionId) => {
  console.log('🔄 会话ID变化:', { oldSessionId, newSessionId })
  if (newSessionId) {
    console.log('📋 开始加载新会话消息:', newSessionId)
    await loadSessionMessages(newSessionId)
  } else {
    console.log('⚠️ 会话ID为空，清空消息列表')
    messages.value = []
  }
}, { immediate: true })

// 发送消息
const sendMessage = async () => {
  const message = inputText.value.trim()
  if (!message && !uploadedImage.value) return

  console.log('🚀 开始发送消息')
  console.log('📝 消息内容:', message)
  console.log('👤 用户信息:', userInfo.value)
  console.log('🎯 会话ID:', props.sessionId)
  if (isTyping.value) return

  // 清空输入并保存临时数据
  const tempImage = uploadedImage.value
  inputText.value = ''
  uploadedImage.value = ''
  imageName.value = ''
  imageSize.value = ''

  // 滚动到底部
  nextTick(() => {
    scrollToBottom()
  })

  // 显示打字指示器
  isTyping.value = true

  // 定义用户消息变量在外层作用域
  let userMessage = null

  try {
    let requestData = { message }
    let ocrText = ''

    // 如果有图片，调用拍照搜题功能
    if (tempImage) {
      try {
        ElMessage.info('正在分析图片，请稍候...')

        // 调用拍照搜题的integrated-search接口
        const { integratedSearch } = await import('@/api/tutor')

        // 将base64转换为File对象
        const response = await fetch(tempImage)
        const blob = await response.blob()
        const file = new File([blob], 'image.jpg', { type: 'image/jpeg' })

        const searchResponse = await integratedSearch({
          userId: userInfo.value?.id || 1,
          imageFile: file,
          sessionName: '图片分析'
        })

        if (searchResponse.success || searchResponse.code === 200) {
          const data = searchResponse.data || searchResponse

          // 提取OCR文字
          ocrText = extractPureTextFromOcr(data.ocrText || data.question || '')

          // 构建消息内容
          if (message.trim()) {
            requestData.message = `用户问题：${message}\n\n图片内容：${ocrText}`
          } else {
            requestData.message = `请分析这张图片，识别出的内容是：${ocrText}`
          }

          // 如果有AI分析结果，添加到消息中
          if (data.analysis) {
            const analysisObj = data.analysis
            if (analysisObj.finalAnswer) {
              requestData.message += `\n\nAI分析结果：${analysisObj.finalAnswer}`
            }
          }

          ElMessage.success('图片分析完成')
        } else {
          throw new Error(searchResponse.message || '图片分析失败')
        }
      } catch (error) {
        console.error('图片分析失败:', error)
        ElMessage.warning('图片分析失败，将使用OCR识别')

        // 降级到OCR识别
        try {
          const ocrResponse = await ocrImage({ imageData: tempImage })
          if (ocrResponse.success || ocrResponse.code === 200) {
            const ocrData = ocrResponse.data || ocrResponse
            ocrText = extractPureTextFromOcr(ocrData.text || ocrData.result || ocrData.content || ocrData)
            requestData.message = message.trim() ?
              `用户问题：${message}\n\n图片中识别出的文字：${ocrText}` :
              `请分析这张图片，识别出的文字内容是：${ocrText}`
          } else {
            requestData.message = message || '请分析这张图片中的内容'
          }
        } catch (ocrError) {
          console.error('OCR识别也失败:', ocrError)
          requestData.message = message || '请分析这张图片中的内容'
        }
      }

      // 保留图片数据用于显示
      requestData.imageData = tempImage
    }

    // 创建用户消息（在OCR识别完成后）
    userMessage = {
      id: ++messageId,
      type: 'user',
      content: message,
      image: tempImage,
      ocrText: ocrText.trim() ? ocrText : null,
      time: new Date()
    }

    messages.value.push(userMessage)

    // 优先使用支持上下文的对话接口
    console.log('🔍 检查对话接口选择条件:', {
      userId: userInfo.value?.id,
      sessionId: props.sessionId,
      hasUserId: !!userInfo.value?.id,
      hasSessionId: !!props.sessionId
    })

    let response
    if (userInfo.value?.id && props.sessionId) {
      console.log('✅ 使用上下文对话接口 chatWithSession')
      console.log('📡 发送请求参数:', {
        userId: userInfo.value.id,
        sessionId: props.sessionId,
        message: requestData.message,
        enableVoice: false
      })

      // 使用支持前端会话ID的上下文对话接口
      response = await chatWithSession({
        userId: userInfo.value.id,
        sessionId: props.sessionId,
        message: requestData.message,
        enableVoice: false
      })

      console.log('📄 chatWithSession响应:', response)
    } else if (userInfo.value?.id) {
      console.log('⚠️ 使用普通用户对话接口 chatWithUser (没有sessionId)')
      console.warn('⚠️ 警告：没有sessionId，对话不会保存到Redis！')

      // 使用带用户ID的聊天接口
      response = await chatWithUser({
        userId: userInfo.value.id,
        message: requestData.message,
        enableVoice: false
      })
    } else {
      console.log('⚠️ 使用简单对话接口 aiChat (没有用户ID)')
      console.warn('⚠️ 警告：没有用户ID，对话不会保存到Redis！')

      // 使用简单聊天接口
      response = await aiChat(requestData)
    }

    let aiResponse = ''
    if (response.success || response.code === 200) {
      const data = response.data || response
      // 处理chat-with-user接口的响应格式
      if (data.aiResponse) {
        aiResponse = data.aiResponse
      } else {
        aiResponse = data.answer || data.response || data.message || data.content || data
      }
    } else {
      aiResponse = response.message || '抱歉，我暂时无法回答您的问题。'
    }

    // 确保响应是字符串类型
    if (typeof aiResponse !== 'string') {
      aiResponse = JSON.stringify(aiResponse)
    }

    const aiMessage = {
      id: ++messageId,
      type: 'ai',
      content: aiResponse,
      time: new Date()
    }

    messages.value.push(aiMessage)
  } catch (error) {
    console.error('发送消息失败:', error)

    // 使用演示回复
    const aiMessage = {
      id: ++messageId,
      type: 'ai',
      content: '抱歉，当前网络连接不稳定。这是一个演示回复：\n\n感谢您的提问！我是AI学习助手，虽然现在无法连接到服务器，但我会尽力帮助您学习。请稍后再试，或者检查网络连接。',
      time: new Date()
    }

    messages.value.push(aiMessage)
  } finally {
    isTyping.value = false

    // Redis会自动保存消息

    // 滚动到底部
    nextTick(() => {
      scrollToBottom()
    })

    // 发送事件（只有在userMessage存在时）
    if (userMessage) {
      emit('message-sent', userMessage)
    }
  }
}

// 处理图片上传
const handleImageUpload = (file) => {
  // 检查文件大小
  if (file.size > 10 * 1024 * 1024) {
    ElMessage.error('图片大小不能超过10MB')
    return false
  }

  // 检查文件类型
  if (!['image/jpeg', 'image/png', 'image/bmp'].includes(file.type)) {
    ElMessage.error('只支持 JPG、PNG、BMP 格式的图片')
    return false
  }

  const reader = new FileReader()
  reader.onload = (e) => {
    uploadedImage.value = e.target.result
    imageName.value = file.name
    imageSize.value = formatFileSize(file.size)
    ElMessage.success('图片上传成功')
  }
  reader.readAsDataURL(file)
  return false // 阻止自动上传
}

// 移除图片
const removeImage = () => {
  uploadedImage.value = ''
  imageName.value = ''
  imageSize.value = ''
  ElMessage.info('图片已删除')
}

// 格式化文件大小
const formatFileSize = (bytes) => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// 选择快速问题
const selectQuickQuestion = (question) => {
  inputText.value = question
  sendMessage()
}

// 发送快速消息
const sendQuickMessage = (message) => {
  inputText.value = message
  sendMessage()
}

// 处理Shift+Enter
const handleShiftEnter = (e) => {
  // 允许换行
}

// 清空消息
const clearMessages = async () => {
  try {
    await ElMessageBox.confirm('确定要清空所有对话记录吗？', '确认清空', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })

    messages.value = []
    ElMessage.success('对话记录已清空')
  } catch (error) {
    // 用户取消
  }
}

// 语音播报消息
const speakMessage = async (content) => {
  if (speakingMessageId.value) {
    // 如果正在播放，停止播放
    speechSynthesis.cancel()
    speakingMessageId.value = null
    return
  }

  try {
    // 检查浏览器是否支持语音合成
    if (!('speechSynthesis' in window)) {
      ElMessage.error('您的浏览器不支持语音播报功能')
      return
    }

    // 创建语音合成实例
    const utterance = new SpeechSynthesisUtterance(content)

    // 设置语音参数
    utterance.lang = 'zh-CN'
    utterance.rate = 0.8
    utterance.pitch = 1
    utterance.volume = 1

    // 设置事件监听
    utterance.onstart = () => {
      speakingMessageId.value = Date.now()
    }

    utterance.onend = () => {
      speakingMessageId.value = null
    }

    utterance.onerror = () => {
      speakingMessageId.value = null
      ElMessage.error('语音播报失败')
    }

    // 开始播报
    speechSynthesis.speak(utterance)

  } catch (error) {
    console.error('语音播报错误:', error)
    ElMessage.error('语音播报失败')
    speakingMessageId.value = null
  }
}

// 复制消息
const copyMessage = async (content) => {
  try {
    await navigator.clipboard.writeText(content)
    ElMessage.success('内容已复制到剪贴板')
  } catch (error) {
    ElMessage.error('复制失败')
  }
}

// 预览图片
const previewImage = (imageUrl) => {
  previewImageUrl.value = imageUrl
  showImagePreview.value = true
}

// 格式化消息内容 - 简洁版
const formatMessage = (content) => {
  if (!content) return ''

  // 确保content是字符串类型
  let text = ''
  if (typeof content === 'string') {
    text = content
  } else if (typeof content === 'object') {
    text = content.text || content.content || content.message || JSON.stringify(content)
  } else {
    text = String(content)
  }

  // 清理和预处理文本
  text = text.trim()

  // 简洁的格式化处理
  return text
    // 清理Markdown符号，保持内容简洁
    .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')  // 保留粗体但简化
    .replace(/\*(.*?)\*/g, '$1')                       // 去除斜体标记
    .replace(/`([^`]+)`/g, '$1')                       // 去除代码标记
    .replace(/```[\s\S]*?```/g, (match) => {
      // 代码块保持换行但去除标记
      return match.replace(/```[\w]*\n?/g, '').replace(/```/g, '')
    })
    // 清理链接格式，只保留文字
    .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
    // 处理列表，保持简洁
    .replace(/^(\d+)\.\s+/gm, '$1. ')
    .replace(/^[-*+]\s+/gm, '• ')
    .replace(/^>\s+/gm, '')                            // 去除引用符号
    // 清理标题符号
    .replace(/^#{1,6}\s+/gm, '')
    // 处理换行，保持段落结构
    .replace(/\n\n+/g, '<br><br>')                     // 段落间距
    .replace(/\n/g, '<br>')                            // 单行换行
    // 清理多余符号
    .replace(/[\/\\|~`]+/g, ' ')                       // 去除特殊符号
    .replace(/\s+/g, ' ')                              // 规范化空格
    .trim()
}

// 格式化时间
const formatTime = (time) => {
  if (!time) return ''
  const date = new Date(time)
  return date.toLocaleTimeString('zh-CN', {
    hour: '2-digit',
    minute: '2-digit'
  })
}

// 滚动到底部
const scrollToBottom = () => {
  if (messagesRef.value) {
    // 使用 setTimeout 确保DOM更新完成后再滚动
    setTimeout(() => {
      // 滚动到最底部，考虑底部内边距
      messagesRef.value.scrollTop = messagesRef.value.scrollHeight + 120
    }, 150) // 增加延迟时间确保DOM完全更新
  }
}

// 从OCR结果中提取纯文字内容
const extractPureTextFromOcr = (ocrResult) => {
  if (!ocrResult) return ''

  // 如果已经是纯文字，直接返回
  if (typeof ocrResult === 'string') {
    try {
      // 尝试解析JSON
      const parsed = JSON.parse(ocrResult)
      return extractTextFromParsedOcr(parsed)
    } catch (e) {
      // 不是JSON，直接返回文字
      return ocrResult.trim()
    }
  }

  // 如果是对象，提取文字内容
  if (typeof ocrResult === 'object') {
    return extractTextFromParsedOcr(ocrResult)
  }

  return String(ocrResult).trim()
}

// 从解析后的OCR对象中提取文字
const extractTextFromParsedOcr = (ocrObj) => {
  if (!ocrObj) return ''

  // 阿里云OCR格式：直接提取content字段
  if (ocrObj.content) {
    return ocrObj.content.trim()
  }

  // 百度OCR格式：提取words_result数组
  if (ocrObj.words_result && Array.isArray(ocrObj.words_result)) {
    return ocrObj.words_result
      .map(item => item.words || '')
      .filter(text => text.trim())
      .join('\n')
      .trim()
  }

  // 通用text字段
  if (ocrObj.text) {
    return ocrObj.text.trim()
  }

  // 如果有subImages数组（阿里云复杂格式）
  if (ocrObj.subImages && Array.isArray(ocrObj.subImages)) {
    let allText = []

    ocrObj.subImages.forEach(subImage => {
      if (subImage.blockInfo && subImage.blockInfo.blockDetails) {
        subImage.blockInfo.blockDetails.forEach(block => {
          if (block.blockContent) {
            allText.push(block.blockContent)
          }
        })
      }
    })

    return allText.join('').trim()
  }

  // 最后尝试直接提取content字段
  return ocrObj.content || ''
}
</script>

<style scoped>
.chat-function {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.modern-chat-container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.9) 100%);
  border-radius: 20px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
  overflow: hidden;
  position: relative;
  border: 1px solid rgba(255, 255, 255, 0.3);
  backdrop-filter: blur(20px);
}

/* 聊天头部 */
.chat-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 24px;
  height: 60px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  position: relative;
  z-index: 10;
  border-radius: 20px 20px 0 0;
  box-shadow: 0 4px 20px rgba(102, 126, 234, 0.3);
  flex-shrink: 0;
}

.chat-header::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(59, 130, 246, 0.3), transparent);
}

.header-left {
  display: flex;
  align-items: center;
  gap: 16px;
  flex: 1;
}

.ai-avatar-large {
  width: 48px;
  height: 48px;
  background: linear-gradient(135deg, #3b82f6, #1d4ed8);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-size: 20px;
  font-weight: 600;
  box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
}

.header-info h3 {
  margin: 0 0 4px 0;
  font-size: 18px;
  font-weight: 600;
}

.header-info p {
  margin: 0;
  font-size: 14px;
  opacity: 0.9;
}

.header-center {
  display: flex;
  justify-content: center;
  flex: 1;
}

.current-user {
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(255, 255, 255, 0.15);
  padding: 8px 16px;
  border-radius: 25px;
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);
  font-size: 14px;
  font-weight: 500;
}

.header-actions {
  display: flex;
  justify-content: flex-end;
  flex: 1;
}

.clear-btn {
  color: white !important;
  background: rgba(255, 255, 255, 0.1) !important;
  border: 1px solid rgba(255, 255, 255, 0.2) !important;
  border-radius: 12px !important;
  padding: 8px 12px !important;
  transition: all 0.3s ease !important;
}

.clear-btn:hover {
  background: rgba(255, 255, 255, 0.2) !important;
  transform: translateY(-1px);
}

/* 消息容器 */
.messages-container {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 24px 24px 120px 24px; /* 增加底部内边距，避免被输入框遮挡 */
  background: #f8fafc;
  scroll-behavior: smooth;
  min-height: 0;
  -webkit-overflow-scrolling: touch;
}

/* 滚动条样式 */
.messages-container::-webkit-scrollbar {
  width: 6px;
}

.messages-container::-webkit-scrollbar-track {
  background: transparent;
}

.messages-container::-webkit-scrollbar-thumb {
  background: rgba(59, 130, 246, 0.3);
  border-radius: 3px;
  transition: background 0.3s ease;
}

.messages-container::-webkit-scrollbar-thumb:hover {
  background: rgba(59, 130, 246, 0.5);
}

/* 欢迎消息 */
.welcome-message {
  text-align: center;
  padding: 40px 20px;
}

.welcome-icon {
  margin-bottom: 20px;
}

.welcome-message h3 {
  margin: 0 0 12px 0;
  color: #303133;
  font-size: 24px;
}

.welcome-message p {
  margin: 0 0 30px 0;
  color: #606266;
  font-size: 16px;
}

.quick-questions h4 {
  margin: 0 0 16px 0;
  color: #303133;
  font-size: 16px;
}

.question-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
}

.question-tag {
  cursor: pointer;
  transition: all 0.3s;
}

.question-tag:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

/* 消息项 */
.message-item {
  width: 100%;
  margin-bottom: 32px;
  animation: messageSlideIn 0.3s ease-out;
}

@keyframes messageSlideIn {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}



/* 用户消息 - 右侧显示 */
.user-message {
  width: 100%;
  display: flex;
  align-items: flex-end;
  gap: 12px;
  justify-content: flex-end;
  margin-bottom: 24px;
  animation: userMessageSlideIn 0.3s ease-out;
}

@keyframes userMessageSlideIn {
  from {
    opacity: 0;
    transform: translateX(20px) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translateX(0) scale(1);
  }
}

.user-message .message-content {
  max-width: 70%;
  background: linear-gradient(135deg, #1890ff 0%, #096dd9 100%);
  color: white;
  padding: 16px 20px;
  border-radius: 20px 20px 6px 20px;
  box-shadow:
    0 4px 16px rgba(24, 144, 255, 0.25),
    0 2px 6px rgba(24, 144, 255, 0.15);
  position: relative;
  word-wrap: break-word;
  line-height: 1.6;
  transition: all 0.3s ease;
}

.user-message .message-content:hover {
  transform: translateY(-1px);
  box-shadow:
    0 6px 24px rgba(24, 144, 255, 0.35),
    0 3px 8px rgba(24, 144, 255, 0.2);
}

.user-message .message-content::after {
  content: '';
  position: absolute;
  bottom: 0;
  right: -6px;
  width: 0;
  height: 0;
  border-left: 6px solid #096dd9;
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
}

.user-message .message-text {
  font-size: 15px;
  margin-bottom: 8px;
}

.user-message .message-time {
  font-size: 11px;
  opacity: 0.85;
  margin-top: 6px;
  text-align: right;
}

.user-avatar {
  flex-shrink: 0;
}

.user-avatar-circle {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: linear-gradient(135deg, #52c41a 0%, #389e0d 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  box-shadow: 0 2px 8px rgba(82, 196, 26, 0.3);
  transition: all 0.3s ease;
}

.user-avatar-circle:hover {
  transform: scale(1.05);
  box-shadow: 0 4px 12px rgba(82, 196, 26, 0.4);
}

/* AI消息 - 左侧显示 */
.ai-message {
  width: 100%;
  display: flex;
  align-items: flex-start;
  justify-content: flex-start;
  gap: 16px;
  margin-bottom: 32px;
  animation: aiMessageSlideIn 0.5s ease-out;
}

@keyframes aiMessageSlideIn {
  from {
    opacity: 0;
    transform: translateX(-20px) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translateX(0) scale(1);
  }
}

.ai-avatar {
  flex-shrink: 0;
  margin-top: 4px;
  position: relative;
}

.ai-avatar-circle {
  width: 36px;
  height: 36px;
  background: linear-gradient(135deg, #722ed1 0%, #531dab 100%);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(114, 46, 209, 0.3);
  position: relative;
  color: white;
  transition: all 0.3s ease;
}

.ai-avatar-circle:hover {
  transform: scale(1.05);
  box-shadow: 0 4px 12px rgba(114, 46, 209, 0.4);
}

.ai-message .message-content {
  flex: 1;
  max-width: 75%;
  background: linear-gradient(145deg, #ffffff 0%, #fafbff 100%);
  padding: 18px 22px;
  border-radius: 6px 20px 20px 20px;
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.08);
  position: relative;
  border: 1px solid #e6f7ff;
  transition: all 0.3s ease;
}

.ai-message .message-content:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
  border-color: #bae7ff;
}

.ai-message .message-content::before {
  content: '';
  position: absolute;
  top: 16px;
  left: -6px;
  width: 0;
  height: 0;
  border-right: 6px solid #ffffff;
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
}

.ai-name {
  font-size: 13px;
  font-weight: 600;
  color: #722ed1;
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.ai-name::before {
  content: '🤖';
  font-size: 14px;
}

.ai-message .message-text {
  font-size: 16px;
  line-height: 1.8;
  color: #2d3748;
  margin-bottom: 16px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  letter-spacing: 0.3px;
}

/* 美化AI消息中的特殊内容 */
.ai-message .message-text strong {
  color: #667eea;
  font-weight: 600;
}

.ai-message .message-text code {
  background: rgba(102, 126, 234, 0.1);
  color: #667eea;
  padding: 2px 6px;
  border-radius: 4px;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 14px;
}

.ai-message .message-text pre {
  background: #f7fafc;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: 16px;
  margin: 12px 0;
  overflow-x: auto;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 14px;
  line-height: 1.5;
}

.ai-message .message-text ul,
.ai-message .message-text ol {
  margin: 12px 0;
  padding-left: 24px;
}

.ai-message .message-text li {
  margin: 6px 0;
  line-height: 1.6;
}

.ai-message .message-text blockquote {
  border-left: 4px solid #667eea;
  background: rgba(102, 126, 234, 0.05);
  margin: 12px 0;
  padding: 12px 16px;
  border-radius: 0 8px 8px 0;
  font-style: italic;
}

.ai-message .message-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid rgba(102, 126, 234, 0.1);
  background: linear-gradient(90deg, transparent 0%, rgba(102, 126, 234, 0.02) 50%, transparent 100%);
  border-radius: 8px;
  padding: 12px 16px;
  margin: 16px -16px -12px -16px;
}

.ai-message .message-time {
  font-size: 12px;
  color: #64748b;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 4px;
}

.ai-message .message-time::before {
  content: '⏰';
  font-size: 10px;
}

.action-buttons {
  display: flex;
  gap: 4px;
}

.action-btn {
  color: #64748b !important;
  border: 1px solid transparent !important;
  border-radius: 20px !important;
  padding: 6px 12px !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  transition: all 0.3s ease !important;
  background: rgba(102, 126, 234, 0.05) !important;
}

.action-btn:hover {
  color: #667eea !important;
  background: rgba(102, 126, 234, 0.1) !important;
  border-color: rgba(102, 126, 234, 0.2) !important;
  transform: translateY(-1px) !important;
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.15) !important;
}

/* 打字机效果 */
.typing-effect {
  overflow: hidden;
  border-right: 2px solid #667eea;
  animation: typing 2s steps(40, end), blink-caret 0.75s step-end infinite;
}

@keyframes typing {
  from { width: 0; }
  to { width: 100%; }
}

@keyframes blink-caret {
  from, to { border-color: transparent; }
  50% { border-color: #667eea; }
}

/* 打字指示器 */
.typing-indicator {
  display: flex;
  align-items: center;
  gap: 4px;
  margin: 12px 0;
  padding: 8px 0;
}

.typing-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #722ed1;
  animation: typingDots 1.4s infinite ease-in-out;
}

.typing-dot:nth-child(1) { animation-delay: -0.32s; }
.typing-dot:nth-child(2) { animation-delay: -0.16s; }
.typing-dot:nth-child(3) { animation-delay: 0s; }

@keyframes typingDots {
  0%, 80%, 100% {
    transform: scale(0.8);
    opacity: 0.5;
  }
  40% {
    transform: scale(1);
    opacity: 1;
  }
}

/* 消息内容美化 */
.message-text h1, .message-text h2, .message-text h3 {
  color: #2d3748;
  margin: 16px 0 12px 0;
  font-weight: 600;
}

.message-text h1 { font-size: 24px; }
.message-text h2 { font-size: 20px; }
.message-text h3 { font-size: 18px; }

.message-text p {
  margin: 12px 0;
  line-height: 1.8;
}

.message-text a {
  color: #667eea;
  text-decoration: none;
  border-bottom: 1px solid rgba(102, 126, 234, 0.3);
  transition: all 0.3s ease;
}

.message-text a:hover {
  color: #764ba2;
  border-bottom-color: #764ba2;
}

/* 数学公式美化 */
.message-text .math {
  background: rgba(102, 126, 234, 0.05);
  border: 1px solid rgba(102, 126, 234, 0.1);
  border-radius: 6px;
  padding: 8px 12px;
  margin: 8px 0;
  font-family: 'Times New Roman', serif;
  font-size: 16px;
  text-align: center;
}

/* 表格美化 */
.message-text table {
  width: 100%;
  border-collapse: collapse;
  margin: 16px 0;
  background: white;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.message-text th,
.message-text td {
  padding: 12px 16px;
  text-align: left;
  border-bottom: 1px solid #e2e8f0;
}

.message-text th {
  background: rgba(102, 126, 234, 0.1);
  font-weight: 600;
  color: #2d3748;
}

.message-text tr:hover {
  background: rgba(102, 126, 234, 0.02);
}

.message-text {
  line-height: 1.7;
  word-break: break-word;
  color: #2c3e50;
  font-size: 15px;
}

/* 段落样式 */
.message-text :deep(.message-paragraph) {
  margin: 0 0 12px 0;
  line-height: 1.7;
}

.message-text :deep(.message-paragraph:last-child) {
  margin-bottom: 0;
}

/* 格式化内容样式 */
.message-text :deep(.message-bold) {
  font-weight: 600;
  color: #1a202c;
}

.message-text :deep(.message-italic) {
  font-style: italic;
  color: #4a5568;
}

.message-text :deep(.inline-code) {
  background: linear-gradient(135deg, #f7fafc 0%, #edf2f7 100%);
  padding: 3px 8px;
  border-radius: 6px;
  font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', monospace;
  font-size: 0.9em;
  color: #e53e3e;
  border: 1px solid #e2e8f0;
  font-weight: 500;
}

.message-text :deep(.code-block-wrapper) {
  margin: 16px 0;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.message-text :deep(.code-block) {
  background: linear-gradient(135deg, #2d3748 0%, #1a202c 100%);
  color: #e2e8f0;
  padding: 20px;
  margin: 0;
  overflow-x: auto;
  font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', monospace;
  font-size: 14px;
  line-height: 1.5;
  border: none;
}

.message-text :deep(.code-block code) {
  background: none;
  padding: 0;
  color: inherit;
}

.message-text :deep(.list-item) {
  margin: 10px 0;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  line-height: 1.6;
}

.message-text :deep(.list-number) {
  color: #3182ce;
  font-weight: 600;
  min-width: 24px;
  flex-shrink: 0;
}

.message-text :deep(.list-bullet) {
  color: #38a169;
  font-weight: 600;
  min-width: 16px;
  flex-shrink: 0;
}

.message-text :deep(.list-content) {
  flex: 1;
  color: #2d3748;
}

.message-text :deep(.message-h2) {
  font-size: 1.5em;
  font-weight: 700;
  color: #1a202c;
  margin: 24px 0 16px 0;
  padding-bottom: 8px;
  border-bottom: 3px solid #3182ce;
  position: relative;
}

.message-text :deep(.message-h2::before) {
  content: '';
  position: absolute;
  bottom: -3px;
  left: 0;
  width: 40px;
  height: 3px;
  background: #38a169;
}

.message-text :deep(.message-h3) {
  font-size: 1.3em;
  font-weight: 600;
  color: #2d3748;
  margin: 20px 0 12px 0;
  position: relative;
  padding-left: 16px;
}

.message-text :deep(.message-h3::before) {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 4px;
  height: 20px;
  background: linear-gradient(135deg, #3182ce 0%, #38a169 100%);
  border-radius: 2px;
}

.message-text :deep(.message-h4) {
  font-size: 1.1em;
  font-weight: 600;
  color: #4a5568;
  margin: 16px 0 10px 0;
}

.message-text :deep(.message-link) {
  color: #3182ce;
  text-decoration: none;
  font-weight: 500;
  border-bottom: 1px solid transparent;
  transition: all 0.3s ease;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.message-text :deep(.message-link:hover) {
  color: #2c5aa0;
  border-bottom-color: #2c5aa0;
  transform: translateY(-1px);
}

.message-text :deep(.link-icon) {
  font-size: 0.8em;
  opacity: 0.7;
}

.message-image img {
  max-width: 200px;
  max-height: 200px;
  border-radius: 8px;
  cursor: pointer;
  margin-bottom: 8px;
}

.ocr-text {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
  padding: 12px 16px;
  background: rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(10px);
  border-radius: 12px;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.3);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  line-height: 1.4;
  word-break: break-all;
}

.ocr-text:hover {
  background: rgba(255, 255, 255, 0.2);
  border-color: rgba(255, 255, 255, 0.4);
  transform: translateY(-1px);
}

.ocr-text .el-icon {
  font-size: 16px;
  opacity: 0.9;
  color: #60a5fa;
  flex-shrink: 0;
}

.ocr-text span {
  flex: 1;
  min-width: 0;
}

.message-time {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.8);
  margin-top: 4px;
  text-align: right;
}

.ai-message .message-time {
  color: #909399;
  text-align: left;
}

.message-actions {
  margin-top: 8px;
  display: flex;
  gap: 8px;
}

/* 打字指示器 */
.typing-indicator {
  display: flex;
  gap: 12px;
  align-items: center;
  margin-bottom: 20px;
}

.typing-dots {
  display: flex;
  gap: 4px;
  padding: 12px 16px;
  background: white;
  border-radius: 18px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.typing-dots span {
  width: 8px;
  height: 8px;
  background: #c0c4cc;
  border-radius: 50%;
  animation: typing 1.4s infinite ease-in-out;
}

.typing-dots span:nth-child(1) { animation-delay: -0.32s; }
.typing-dots span:nth-child(2) { animation-delay: -0.16s; }

@keyframes typing {
  0%, 80%, 100% { transform: scale(0.8); opacity: 0.5; }
  40% { transform: scale(1); opacity: 1; }
}

/* 输入区域 */
.input-area {
  height: 80px;
  border-top: 1px solid #e2e8f0;
  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
  position: sticky;
  bottom: 0;
  z-index: 10;
  border-radius: 0 0 16px 16px;
  backdrop-filter: blur(20px);
  box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.1);
  flex-shrink: 0;
}

.input-container {
  padding: 12px 20px;
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
  justify-content: center;
}

.image-preview {
  margin-bottom: 12px;
  padding: 12px;
  background: #f8f9fa;
  border-radius: 12px;
  border: 1px solid #e4e7ed;
}

.preview-image {
  position: relative;
  display: inline-block;
  margin-bottom: 8px;
}

.preview-image img {
  max-width: 120px;
  max-height: 120px;
  border-radius: 8px;
  display: block;
}

.image-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.preview-image:hover .image-overlay {
  opacity: 1;
}

.image-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  color: #606266;
}

.image-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin-right: 8px;
}

.image-size {
  color: #909399;
}

.input-row {
  display: flex;
  gap: 12px;
  align-items: flex-end;
}

.message-input {
  flex: 1;
}

.input-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}

.send-btn {
  width: 48px;
  height: 48px;
  border-radius: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.input-tips {
  margin-top: 8px;
  font-size: 12px;
  color: #909399;
  text-align: center;
}

/* 滚动条样式 */
.messages-container::-webkit-scrollbar {
  width: 6px;
}

.messages-container::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.messages-container::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.messages-container::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

/* 响应式设计 */
/* 平板横屏适配 */
@media (min-width: 769px) and (max-width: 1200px) and (orientation: landscape) {
  .chat-card {
    height: calc(100vh - 120px);
    min-height: 450px;
  }

  .messages-container {
    padding: 20px 20px 100px 20px;
  }

  .input-area {
    padding: 16px 20px;
  }

  .user-message, .ai-message {
    margin-bottom: 16px;
  }

  .message-content {
    max-width: 85%;
  }
}

/* 小屏幕适配 */
@media (max-width: 768px) {
  .chat-card {
    height: calc(100vh - 80px);
    min-height: 400px;
  }

  .messages-container {
    padding: 16px;
    max-height: calc(100% - 120px);
  }

  .user-message .message-content,
  .ai-message .message-content {
    max-width: 85%;
  }

  .user-avatar-circle,
  .ai-avatar-circle {
    width: 32px;
    height: 32px;
  }

  .ai-name {
    font-size: 12px;
    margin-bottom: 8px;
  }

  .user-message .message-time,
  .ai-message .message-time {
    font-size: 10px;
  }

  .input-row {
    flex-direction: column;
    gap: 8px;
  }

  .input-actions {
    align-self: flex-end;
  }

  /* 移动端格式化内容优化 */
  .message-text :deep(.code-block) {
    font-size: 0.8em;
    padding: 12px;
    margin: 8px 0;
  }

  .message-text :deep(.message-h2) {
    font-size: 1.2em;
    margin: 12px 0 8px 0;
  }

  .message-text :deep(.message-h3) {
    font-size: 1.1em;
    margin: 10px 0 6px 0;
  }

  .message-text :deep(.list-item) {
    margin: 6px 0;
    padding-left: 12px;
  }
}
</style>
